

//_______________________________________________________________________________________________________________
/****************************************************************************************************************/
/*                                                                                                              */
/*                     Q U E U E   O F   M E S S A G E S                                                        */
/*                                                                                                              */
/****************************************************************************************************************/

#if defined(OS_ENABLE_INT_QMSG)
    #define __OS_QMSG_DI()       {_OS_temp = OS_DI();}
    #define __OS_QMSG_RI()       {OS_RI(_OS_temp);}
#else
    #define __OS_QMSG_DI()
    #define __OS_QMSG_RI()
#endif



#ifdef OS_ENABLE_QMSG

extern void _OS_SendQMsg (OST_QMSG *pQMsg, OST_MSG Msg);
extern OST_MSG _OS_GetQMsg (OST_QMSG *pQMsg);


//------------------------------------------------------------------------------
// Create queue

#define OS_CreateQMsg(qmsg, buffer, size)               \
    {                                                   \
        __OS_QMSG_DI();                                 \
        (qmsg).Q.cSize = size;                          \
        (qmsg).Q.cBegin = 0;                            \
        (qmsg).Q.cFilled = 0;                           \
        (qmsg).pMsg = (OST_MSG*)buffer;                 \
        __OS_QMSG_RI();                                 \
    }

//------------------------------------------------------------------------------
// Check for any message present in queue

#define OS_CheckQMsg(qmsg)        ((qmsg).Q.cFilled)

//------------------------------------------------------------------------------
// Check for queue is full

#define OS_IsQMsgFull(qmsg)       ((qmsg).Q.cFilled == (qmsg).Q.cSize)

//------------------------------------------------------------------------------
// Check for free room in queue

#define OS_IsQMsgFree(qmsg)       ((qmsg).Q.cFilled ^ (qmsg).Q.cSize)


//------------------------------------------------------------------------------
// Clear queue

#define OS_ClearQMsg(qsmsg)        { (qmsg).Q.cFilled = 0; }

//------------------------------------------------------------------------------
// Send message via queue. If queue full then wait for free place


#define OS_SendQMsg(qmsg, value)                                        \
    {                                                                   \
        if (OS_IsQMsgFull(qmsg))                                        \
        {                                                               \
            _OS_WAIT_EVENT(OS_IsQMsgFree(qmsg));                        \
        }                                                               \
        _OS_SendQMsg(&(qmsg), value);                                   \
    }                                                                   \


//------------------------------------------------------------------------------
// Send message via queue. If queue full then wait for free place. Exit if timeout expired.

#define OS_SendQMsgTimeout(qmsg, value, timeout)                        \
    {                                                                   \
        OS_Flags.bTimeout = 0;                                          \
        if (OS_IsQMsgFull(qmsg))                                        \
        {                                                               \
            _OS_WAIT_EVENT_TIMEOUT(OS_IsQMsgFree(qmsg), timeout);       \
        }                                                               \
        if (!OS_IsTimeout()) {                                          \
            _OS_SendQMsg(&(qmsg), value);                               \
        }                                                               \
    }

//------------------------------------------------------------------------------
// Send message via queue. If queue is full then most rearly message will be pushed out.

#define OS_SendQMsgNoWait(qmsg, value)                                  \
    {                                                                   \
        _OS_SendQMsg(&(qmsg), value);                                   \
    }


//------------------------------------------------------------------------------
// Send message via queue from interrupt. If queue is full then most rearly message will be pushed out.

#if defined(OS_ENABLE_INT_QMSG)
    extern void _OS_IntSendQMsg (OST_QMSG *pQMsg, OST_MSG Msg);

    #define OS_IntSendQMsgNoWait(qmsg, value)                               \
        {                                                                   \
            _OS_IntSendQMsg(&(qmsg), value);                                \
        }
#endif

//------------------------------------------------------------------------------
// Wait message from queue. After accepting message will be deleted from queue.

#define OS_WaitQMsg(qmsg, os_msg_type_var)                              \
    {                                                                   \
        _OS_WAIT_EVENT(OS_CheckQMsg(qmsg));                             \
        OS_AcceptQMsg(qmsg,os_msg_type_var)                             \
    }

//------------------------------------------------------------------------------
// Wait message from queue. After accepting message will be deleted from queue. Exit if timeout expired.

#define OS_WaitQMsgTimeout(qmsg, os_msg_type_var, timeout)              \
    {                                                                   \
        _OS_WAIT_EVENT_TIMEOUT(OS_CheckQMsg(qmsg), timeout);            \
        if (!OS_IsTimeout())                                            \
            OS_AcceptQMsg(qmsg,os_msg_type_var)                         \
    }

//------------------------------------------------------------------------------
// 
#define OS_AcceptQMsg(qmsg,os_msg_type_var)                         \
    {                                                               \
        __OS_QMSG_DI();                                             \
        os_msg_type_var = _OS_GetQMsg(&(qmsg));                     \
        __OS_QMSG_RI();                                             \
    }                                                               \



#endif

